#ifndef _LIB_CACHE_H
#define _LIB_CACHE_H

#define LIB_CACHE_NAMESPACE			LibCache
#define LIB_CACHE_NAMESPACE_BEGIN	namespace LIB_CACHE_NAMESPACE {
#define LIB_CACHE_NAMESPACE_END		}
#define USING_LIB_CACHE				using namespace LIB_CACHE_NAMESPACE;

#ifdef LIBCACHE_EXPORTS
#define LIB_CACHE_EXPORT __declspec(dllexport)
#else
#define LIB_CACHE_EXPORT
#endif

#ifndef byte
#define byte unsigned char 
#endif

#ifndef NULL
#define NULL 0
#endif

#define DEFAULT_FOLDER_CACHE_SIZE		32 * 1024 * 1024
#define DEFAULT_MEM_CACHE_SIZE			8 * 1024 * 1024
#define DEFAULT_CACHE_ENTRY_SZIE		2 * 1024 * 1024

LIB_CACHE_NAMESPACE_BEGIN

class ICacheEntry
{
public:
	virtual ~ICacheEntry() {}
	virtual bool Read(byte* buffer, const size_t& bufferSize, size_t& readSize) = 0;
	virtual bool Write(const byte* buffer, const size_t& bufferSize, size_t& writeSize) = 0;
	virtual bool GetRawBuffer(byte** buffer, size_t& bufferSize) const = 0;
	virtual bool SetRawBuffer(byte* buffer, size_t& bufferSize) = 0;
	virtual bool SeekPointer(int position, int begin = 0) = 0;
	virtual bool PersistData(const char* path = NULL, bool absolutePath = true) const = 0;
	virtual bool LoadPersistData(const char* path = NULL, bool absolutePath = true) = 0;
	virtual size_t GetSize() const = 0;
	virtual bool SetSize(const size_t& size) = 0;
	virtual const char* GetName() const = 0;
	virtual bool SetName(const char* name) = 0;
	virtual bool Clone(ICacheEntry** cacheEntry) const = 0;
	virtual bool Lock(bool read = true) const = 0;
	virtual bool UnLock() const = 0;
	virtual bool TryLock(bool read = true) const = 0;
	virtual bool IsDirty() const = 0;
	virtual bool CanWrite() const = 0;
};

class ICacheManager 
{
public:
	virtual bool Initialize(const char* cacheBaseDir = NULL,
							bool checkHash = true, 
							const size_t& maxMemSize = DEFAULT_MEM_CACHE_SIZE,
							const size_t& maxFolderSize = DEFAULT_FOLDER_CACHE_SIZE,
							const size_t& maxCacheEntrySize = DEFAULT_CACHE_ENTRY_SZIE) = 0;

	virtual bool Destroy() = 0;

	virtual bool Refresh() = 0;

	virtual const char* GetCacheBaseDir() const = 0;

	virtual bool GetCache(const char* name, 
							ICacheEntry** cacheEntry = NULL, 
							bool checkDisk = true, 
							bool checkHash = true) const = 0;

	virtual bool AddCache(const char* name, 
							const ICacheEntry* cacheEntry, 
							bool writeToDisk = true,
							bool checkHash = true) = 0;

	virtual bool AddCache(const char* name, 
							const byte* data, 
							const size_t size,
							ICacheEntry** cacheEntry = NULL,
							bool writeToDisk = true,
							bool checkHash = true) = 0;

	virtual bool RemoveCache(const char* name, bool removeDiskCopy = false) = 0;

	virtual bool CreateCacheEntry(const char* name, ICacheEntry** cacheEntry) const = 0;

	virtual bool ReleaseCacheEntry(ICacheEntry* cacheEntry) const = 0;

	virtual bool Lock(bool read = true) const = 0;

	virtual bool UnLock() const = 0;

	virtual bool TryLock(bool read = true) const = 0;

	static LIB_CACHE_EXPORT ICacheManager* CreateCacheManager();
};

LIB_CACHE_NAMESPACE_END

#endif //_LIB_CACHE_H